/**********************************
* @file: copy
* @desc: copy file or dir
* @author: langlang
* @version: 1.0.0
* @date: 2022/03/29
***********************************/
// 缺点 这检测不到什么是复制结束

const fs = require( "fs" );
const chalk = require("chalk");

/**
 *  copy main function
 *
 * @param  {String} from which file or directory you wanna copy
 * @param  {String} to   the target file or dir you copyed
 */
 module.exports =  async function copy(from, to, projectName) {
	if(!from){
		console.log(error("pleace input the file or directory you wanna copy"));
		return ;
	}
	try{
		if(from === "--help"){
			help();
			return;
		}
		await isExist(from);
		if(!to){
			console.log(error("pleace  the target file or directory you wanna copy"));
			return;
		}
		const type = await pathType(from);
		if(type == "file"){
			copyFile(from ,to); // file copy
		}else{
			copyDir(from,to,projectName); // directory copy
		}
	}catch(err){
		console.log(error(err));
	}
}

// execute fuzhi
// fuzhi(argv[2],argv[3]);

/**
 * copy file
 *
 * @param  {String} from copied file
 * @param  {String} to   target file
 */
function copyFile(from, to) {
	fs.writeFileSync(to, fs.readFileSync(from));
	console.log(success(from,to));
}

/**
 * copy directory
 *
 * @param  {String} from
 * @param  {String} to
 */
async function copyDir(from, to, projectName) {
	console.log(chalk.magenta(`🏇 copy ${from} `));
	try{
		await isExist(to);
	}catch(err){
		fs.mkdirSync(to);
	}
	await fs.readdir(from, (err, paths) => {
		paths.forEach((path)=>{
			var src = `${from}/${path}`;
			var dist = `${to}/${path}`;
			fs.stat(src,(err, stat)=> {
				if(stat.isFile()) {
					fs.writeFileSync(dist, fs.readFileSync(src));
          if(path  == 'build.json'){
            writeBuild(dist,projectName)
          }
					console.log(chalk.magenta(`🏇 copy ${src} `));
				} else if(stat.isDirectory()) {
					copyDir(src, dist, projectName);
				}
			});
		});
	});
}

const writeBuild = (path,projectName)=>{
  const dataJson = { }
  dataJson[projectName] = {}
  fs.writeFile(path, JSON.stringify(dataJson, "", "\t"), "utf-8", function (err) {
    if (err) {
      throw new Error("build.json写入失败");
    } else {
      console.log("build.json写入成功");
    }
  });
}

/**
 * is exists
 *
 * @param  {String} file
 * @return {Promise}
 */
function isExist(path){
	return new Promise((resolve,reject)=>{
		fs.access(path,  (err) => {
			if(err!==null){
				reject(`${path} does not exist`);
			}else{
				resolve(true);
			}
		});
	});
}

/**
 * file or a folder
 *
 * @param  {String} path
 * @return {Promise}
 */
function pathType(path){
	return new Promise((resolve,reject)=>{
		fs.stat(path,(err,stats)=>{
			if(err === null){
				if(stats.isDirectory()){
					resolve("dir"); // it's directory
				}else if(stats.isFile()){
					resolve("file"); // it's file
				}
			}else{
				reject(error(path)); // files or directory don't exist
			}
		});
	});
}

/**
 * help output
 *
 * @return {String}  help description
 */
function help(){
	console.log(chalk.blueBright(`
fuzhi: 0.08
Usage: https://github.com/leinov/fuzhi
options:
[from] [to]       copy [from] file or directory to [to]
example:
fuzhi a.js b.js   copy a.js to b.js
fuzhi dirA dirB   copy directory dirA to dirB
		`));
}

/**
 * error output
 *
 * @param  {String} path
 * @return {String}
 */
function error(msg){
	return chalk.red(`
⛑ ⛑ ⛑
error: ${msg}
Use --help to display the cli options.
  `);
}

/**
 * success output
 *
 * @param  {String} path
 * @return {String}
 */
function success(from,to){
	return chalk.green(`
******************************************
*
* 💯
*
* ok: ${from} copy to ${to} success
*
******************************************
  `);
}